/**
 * 金牛座表结构文档生成工具（NodeJS版本）
 * 
 * 功能：
 * - 获取表结构信息
 * - 生成TypeScript接口定义
 * - 生成表文档
 * - 记录日志
 */

const fs = require('fs');
const path = require('path');
const https = require('https');
const http = require('http');
const { apiLogger } = require('./apiLogger');
const { generateApiExample } = require('./API_TEMPLATES');

// 加载配置文件
const loadConfig = () => {
    const configPath = path.resolve(__dirname, './env.config');

    if (!fs.existsSync(configPath)) {
        console.error('错误：找不到配置文件', configPath);
        process.exit(1);
    }

    try {
        console.log('正在加载配置文件...');
        const config = {};
        const content = fs.readFileSync(configPath, 'utf8');

        // 解析配置文件中的键值对
        content.split('\n').forEach(line => {
            // 跳过注释和空行
            if (line.trim().startsWith('#') || !line.trim()) return;

            // 提取键值对
            const match = line.match(/^([A-Z0-9_]+)="([^"]*)"/);
            if (match) {
                const [, key, value] = match;
                config[key] = value;

                // 处理特殊情况，如引用其他变量
                if (value.includes('${')) {
                    const refMatch = value.match(/\${([^}]*)}/);
                    if (refMatch && config[refMatch[1]]) {
                        config[key] = value.replace(/\${[^}]*}/, config[refMatch[1]]);
                    }
                }
            }
        });

        console.log('配置文件加载成功');
        return config;
    } catch (error) {
        console.error('加载配置文件失败:', error);
        process.exit(1);
    }
};

const CONFIG = loadConfig();

// 配置信息
const AUTO_API_BASE_URL = process.env.AUTO_API_BASE_URL || CONFIG.AUTO_API_BASE_URL;
const PROJECT_ID = process.env.PROJECT_ID || CONFIG.PROJECT_ID;
let SCHEMA_NAME = process.env.SCHEMA_NAME || CONFIG.SCHEMA_NAME;
const REFRESH_TOKEN = process.argv.includes('--refresh-token'); // 强制刷新token
const ENABLE_API_LOGGING = process.argv.includes('--log-api');
const CLEAR_API_LOGS = process.argv.includes('--clear-api-logs');
const MAX_TOKEN_RETRIES = 3; // 获取token的最大重试次数
const OFFLINE_MODE = process.argv.includes('--offline'); // 是否使用离线模式
const USE_MOCK_TOKEN = process.argv.includes('--mock-token'); // 是否使用模拟token

// 使用配置文件中的目录配置或使用默认值
const OUTPUT_BASE_DIR = path.resolve(__dirname, CONFIG.OUTPUT_BASE_DIR || '../');
const RAW_DATA_DIR = path.resolve(OUTPUT_BASE_DIR, CONFIG.RAW_DATA_DIR || 'raw-data');
const CONFIG_DIR = path.resolve(OUTPUT_BASE_DIR, CONFIG.CONFIG_DIR || 'config');
const LOGS_DIR = path.resolve(OUTPUT_BASE_DIR, CONFIG.LOGS_DIR || 'logs');
const TYPES_DIR = path.resolve(OUTPUT_BASE_DIR, CONFIG.TYPES_DIR || 'types');
const TABLES_DIR = path.resolve(OUTPUT_BASE_DIR, CONFIG.TABLES_DIR || 'tables');

// 日志相关配置
const LOG_ENABLED = true;
const LOG_DIR = LOGS_DIR;
const LOG_FILE = path.join(LOG_DIR, `table-docs-generate-${new Date().toISOString().slice(0, 10)}.log`);
const JSON_DATA_DIR = RAW_DATA_DIR;
const TABLE_LOG_DIR = path.join(LOG_DIR, 'tables');
const TOKEN_CACHE_FILE = path.join(LOG_DIR, 'token-cache.json');
const TOKEN_CACHE_EXPIRE = parseInt(CONFIG.TOKEN_CACHE_EXPIRE || '604800000'); // token缓存有效期，7天
const MOCK_TOKEN = CONFIG.DEFAULT_MOCK_TOKEN || 'mock-token-for-testing'; // 模拟token

console.log(`使用的配置：
- API地址: ${AUTO_API_BASE_URL}
- 项目ID: ${PROJECT_ID}
- Schema名称: ${SCHEMA_NAME}
- 原始数据目录: ${JSON_DATA_DIR}
- 日志目录: ${LOG_DIR}
- 类型定义目录: ${TYPES_DIR}
- 表文档目录: ${TABLES_DIR}
`);

// 创建日志目录
if (LOG_ENABLED && !fs.existsSync(LOG_DIR)) {
    fs.mkdirSync(LOG_DIR, { recursive: true });
}

// 创建表日志目录
if (LOG_ENABLED && !fs.existsSync(TABLE_LOG_DIR)) {
    fs.mkdirSync(TABLE_LOG_DIR, { recursive: true });
}

// 创建JSON数据目录
if (!fs.existsSync(JSON_DATA_DIR)) {
    fs.mkdirSync(JSON_DATA_DIR, { recursive: true });
}

// 创建输出目录
if (!fs.existsSync(TYPES_DIR)) {
    fs.mkdirSync(TYPES_DIR, { recursive: true });
}

if (!fs.existsSync(TABLES_DIR)) {
    fs.mkdirSync(TABLES_DIR, { recursive: true });
}

// JSON数据工具
const jsonDataManager = {
    saveData: (tableName, dataType, data) => {
        try {
            const tableDir = path.join(JSON_DATA_DIR, tableName);
            if (!fs.existsSync(tableDir)) {
                fs.mkdirSync(tableDir, { recursive: true });
            }

            const filePath = path.join(tableDir, `${dataType}.json`);
            fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
            logger.log(`保存${tableName}的${dataType}数据到: ${filePath}`);

            // 同时记录到表日志
            logger.tableLog(tableName, 'SAVE_DATA', `保存 ${dataType} 数据`, { path: filePath, size: Buffer.byteLength(JSON.stringify(data)) });

            return filePath;
        } catch (error) {
            logger.error(`保存${tableName}的${dataType}数据失败`, error);
            return null;
        }
    },

    getData: (tableName, dataType) => {
        try {
            const filePath = path.join(JSON_DATA_DIR, tableName, `${dataType}.json`);
            if (!fs.existsSync(filePath)) {
                logger.warn(`${tableName}的${dataType}数据文件不存在: ${filePath}`);
                return null;
            }

            const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
            logger.log(`读取${tableName}的${dataType}数据，大小: ${Buffer.byteLength(JSON.stringify(data))} 字节`);
            return data;
        } catch (error) {
            logger.error(`读取${tableName}的${dataType}数据失败`, error);
            return null;
        }
    },

    getAllTables: () => {
        try {
            const allTableNames = jsonDataManager.getData('metadata', 'all_table_names');
            const tablesSummary = jsonDataManager.getData('metadata', 'tables_summary');

            if (tablesSummary) {
                return tablesSummary;
            } else if (allTableNames) {
                return allTableNames.map(name => ({ tableName: name }));
            } else {
                // 通过遍历JSON_DATA_DIR目录获取所有表名
                const directories = fs.readdirSync(JSON_DATA_DIR, { withFileTypes: true })
                    .filter(dirent => dirent.isDirectory() && dirent.name !== 'metadata')
                    .map(dirent => dirent.name);

                logger.log(`通过目录扫描获取到 ${directories.length} 个表`);
                return directories.map(name => ({ tableName: name }));
            }
        } catch (error) {
            logger.error('获取所有表信息失败', error);
            return [];
        }
    },

    getTableRelations: () => {
        try {
            const tables = jsonDataManager.getAllTables();
            const relations = [];

            for (const table of tables) {
                const tableName = table.tableName;
                const columns = jsonDataManager.getData(tableName, 'columns');

                if (!columns) continue;

                // 查找可能的外键关系（这里用简单的名称匹配模拟）
                for (const column of columns) {
                    // 如果列名形如 xxx_id，可能是外键
                    if (/_id$/.test(column.columnName)) {
                        // 移除_id后缀，得到可能的表名
                        const possibleRefTable = column.columnName.replace(/_id$/, '');

                        // 查找这个表是否存在
                        const refTableExists = tables.some(t =>
                            t.tableName === possibleRefTable ||
                            t.tableName.endsWith(`_${possibleRefTable}`)
                        );

                        if (refTableExists) {
                            relations.push({
                                sourceTable: tableName,
                                sourceColumn: column.columnName,
                                targetTable: possibleRefTable,
                                targetColumn: 'id', // 假设目标是主键id
                                relationType: 'POSSIBLE_FK'
                            });
                        }
                    }
                }
            }

            jsonDataManager.saveData('metadata', 'table_relations', relations);
            return relations;
        } catch (error) {
            logger.error('分析表关系失败', error);
            return [];
        }
    },

    checkDataIntegrity: () => {
        try {
            const tables = jsonDataManager.getAllTables();
            const integrityReport = {
                tables: [],
                missingInfoCount: 0,
                missingColumnsCount: 0,
                timestamp: new Date().toISOString()
            };

            for (const table of tables) {
                const tableName = table.tableName;
                const info = jsonDataManager.getData(tableName, 'info');
                const columns = jsonDataManager.getData(tableName, 'columns');

                const tableReport = {
                    tableName: tableName,
                    hasInfo: !!info,
                    hasColumns: !!columns,
                    columnsCount: columns ? columns.length : 0,
                    missingFields: []
                };

                if (!info) {
                    integrityReport.missingInfoCount++;
                    tableReport.missingFields.push('info');
                }

                if (!columns) {
                    integrityReport.missingColumnsCount++;
                    tableReport.missingFields.push('columns');
                }

                integrityReport.tables.push(tableReport);
            }

            jsonDataManager.saveData('metadata', 'data_integrity_report', integrityReport);
            return integrityReport;
        } catch (error) {
            logger.error('检查数据完整性失败', error);
            return null;
        }
    },

    exportTableToCsv: (tableName, dataType = 'columns') => {
        try {
            const data = jsonDataManager.getData(tableName, dataType);
            if (!data || !Array.isArray(data)) {
                logger.warn(`${tableName}的${dataType}数据不存在或不是数组`);
                return null;
            }

            // 获取所有可能的列
            const allKeys = new Set();
            data.forEach(item => {
                Object.keys(item).forEach(key => allKeys.add(key));
            });

            const headers = Array.from(allKeys);
            let csvContent = headers.join(',') + '\n';

            data.forEach(item => {
                const row = headers.map(header => {
                    const val = item[header];
                    // 处理值中的逗号和换行符
                    if (val === null || val === undefined) return '';
                    const strVal = String(val).replace(/"/g, '""');
                    return /[,\n"]/.test(strVal) ? `"${strVal}"` : strVal;
                });
                csvContent += row.join(',') + '\n';
            });

            const csvDir = path.join(JSON_DATA_DIR, 'csv');
            if (!fs.existsSync(csvDir)) {
                fs.mkdirSync(csvDir, { recursive: true });
            }

            const csvFilePath = path.join(csvDir, `${tableName}_${dataType}.csv`);
            fs.writeFileSync(csvFilePath, csvContent);
            logger.log(`导出${tableName}的${dataType}数据到CSV: ${csvFilePath}`);

            return csvFilePath;
        } catch (error) {
            logger.error(`导出${tableName}的${dataType}数据到CSV失败`, error);
            return null;
        }
    },

    exportAllTablesToExcel: () => {
        try {
            const tables = jsonDataManager.getAllTables();
            logger.log(`准备导出 ${tables.length} 个表的数据为CSV格式`);

            const results = tables.map(table => {
                const tableName = table.tableName;
                return {
                    tableName,
                    columnsFile: jsonDataManager.exportTableToCsv(tableName, 'columns'),
                    infoFile: jsonDataManager.getData(tableName, 'info') ?
                        jsonDataManager.exportTableToCsv(tableName, 'info') : null
                };
            });

            // 导出表的汇总信息
            const tablesSummary = jsonDataManager.getData('metadata', 'tables_summary');
            if (tablesSummary) {
                jsonDataManager.saveData('metadata', 'export_summary', {
                    timestamp: new Date().toISOString(),
                    tablesCount: tables.length,
                    exportResults: results
                });
            }

            return results;
        } catch (error) {
            logger.error('导出所有表数据失败', error);
            return [];
        }
    }
};

// 日志工具
const logger = {
    log: (message) => {
        const timestamp = new Date().toISOString();
        const logMessage = `[${timestamp}] INFO: ${message}\n`;

        console.log(message);

        if (LOG_ENABLED) {
            fs.appendFileSync(LOG_FILE, logMessage);
        }
    },
    error: (message, error) => {
        const timestamp = new Date().toISOString();
        let logMessage = `[${timestamp}] ERROR: ${message}\n`;

        if (error && error.message) {
            logMessage += `[${timestamp}] ERROR DETAILS: ${error.message}\n`;
            if (error.stack) {
                logMessage += `[${timestamp}] STACK: ${error.stack}\n`;
            }
        }

        console.error(message);
        if (error) console.error(error);

        if (LOG_ENABLED) {
            fs.appendFileSync(LOG_FILE, logMessage);
        }
    },
    warn: (message) => {
        const timestamp = new Date().toISOString();
        const logMessage = `[${timestamp}] WARN: ${message}\n`;

        console.warn(message);

        if (LOG_ENABLED) {
            fs.appendFileSync(LOG_FILE, logMessage);
        }
    },
    // 为表创建一个专用的日志记录函数
    tableLog: (tableName, action, message, details = null) => {
        const timestamp = new Date().toISOString();
        const logDate = timestamp.slice(0, 10);
        const tableLogFile = path.join(TABLE_LOG_DIR, `${tableName}-${logDate}.log`);

        let logMessage = `[${timestamp}] ${action}: ${message}\n`;

        if (details) {
            if (typeof details === 'object') {
                logMessage += `[${timestamp}] DETAILS: ${JSON.stringify(details, null, 2)}\n`;
            } else {
                logMessage += `[${timestamp}] DETAILS: ${details}\n`;
            }
        }

        if (LOG_ENABLED) {
            fs.appendFileSync(tableLogFile, logMessage);
            // 同时也添加到主日志中
            fs.appendFileSync(LOG_FILE, `[${timestamp}] TABLE_LOG [${tableName}] ${action}: ${message}\n`);
        }

        console.log(`[表:${tableName}] ${action}: ${message}`);
        return { timestamp, action, message, details };
    },
    // 记录表的变更历史
    recordTableChanges: (tableName, changeType, changeBy, description, version = '1.0') => {
        const timestamp = new Date().toISOString();
        const date = timestamp.slice(0, 10);
        const changeLogFile = path.join(TABLE_LOG_DIR, `${tableName}-changes.json`);

        let changeHistory = [];

        // 如果已存在变更历史文件，则读取它
        if (fs.existsSync(changeLogFile)) {
            try {
                const fileContent = fs.readFileSync(changeLogFile, 'utf8');
                changeHistory = JSON.parse(fileContent);
            } catch (error) {
                logger.error(`读取表 ${tableName} 的变更历史失败`, error);
            }
        }

        // 添加新的变更记录
        const changeRecord = {
            date,
            timestamp,
            version,
            changeType,
            changeBy,
            description
        };

        changeHistory.push(changeRecord);

        // 保存变更历史
        try {
            fs.writeFileSync(changeLogFile, JSON.stringify(changeHistory, null, 2));
            logger.tableLog(tableName, 'CHANGE_RECORD', `记录变更: ${changeType} - ${description}`);
        } catch (error) {
            logger.error(`保存表 ${tableName} 的变更历史失败`, error);
        }

        return changeRecord;
    },
    saveJsonData: (tableName, dataType, data) => {
        return jsonDataManager.saveData(tableName, dataType, data);
    },
    // 记录表的处理开始
    startTableProcessing: (tableName, tableComment) => {
        return logger.tableLog(tableName, 'START', `开始处理表 ${tableName} (${tableComment || '无注释'})`, {
            time: new Date().toISOString(),
            script: __filename
        });
    },
    // 记录表的处理完成
    finishTableProcessing: (tableName, stats) => {
        return logger.tableLog(tableName, 'FINISH', `完成处理表 ${tableName}`, stats);
    }
};

// 记录脚本启动信息
logger.log('===============================================');
logger.log('金牛座表结构文档生成工具脚本启动');
logger.log(`API基础URL: ${AUTO_API_BASE_URL}`);
logger.log(`项目ID: ${PROJECT_ID}`);
logger.log(`数据库Schema: ${SCHEMA_NAME}`);
logger.log('===============================================');

// 将MySQL类型转换为TypeScript类型
const mysqlToTsType = {
    'varchar': 'string',
    'char': 'string',
    'text': 'string',
    'tinytext': 'string',
    'mediumtext': 'string',
    'longtext': 'string',
    'int': 'number',
    'integer': 'number',
    'tinyint': 'number',
    'smallint': 'number',
    'mediumint': 'number',
    'bigint': 'number',
    'float': 'number',
    'double': 'number',
    'decimal': 'number',
    'date': 'string',
    'time': 'string',
    'datetime': 'string',
    'timestamp': 'string',
    'year': 'number',
    'boolean': 'boolean',
    'json': 'any',
    'enum': 'string',
    'set': 'string[]',
    'blob': 'any',
    'binary': 'any',
    'bit': 'boolean',
    'geometry': 'any',
    'point': 'any',
    'linestring': 'any',
    'polygon': 'any',
    'multipoint': 'any',
    'multilinestring': 'any',
    'multipolygon': 'any',
    'geometrycollection': 'any'
};

// 从配置文件中获取启用的表列表，不再使用硬编码表名
function getTableNamesFromConfig() {
    // 通过配置管理工具获取启用的表列表
    try {
        const configManager = require('./configAdapter');
        const enabledTables = configManager.getEnabledTables();
        console.log(`从配置中找到 ${enabledTables.length} 个启用的表`);
        return enabledTables;
    } catch (error) {
        console.error('获取启用表列表失败:', error);
        // 失败时返回默认表列表作为备选
        return ['demo_table'];
    }
}

// 获取需要处理的表名列表
const tableNames = getTableNamesFromConfig();

// 配置文件相关
const CONFIG_PATH = path.resolve(__dirname, '../config');
const CONFIG_FILE = path.join(CONFIG_PATH, 'tables-config.json');

// 尝试导入配置工具模块
let tableConfigManager = null;
try {
    tableConfigManager = require('./configAdapter');
    logger.log('加载表配置管理工具成功');
} catch (error) {
    logger.warn('无法加载表配置管理工具，将使用默认配置：' + error.message);
}

/**
 * 读取表配置信息
 * @returns {Object} 表配置对象
 */
function getTablesConfig() {
    // 如果有配置管理工具，使用它
    if (tableConfigManager) {
        return tableConfigManager.readExistingConfig();
    }

    // 否则，尝试直接读取配置文件
    try {
        if (fs.existsSync(CONFIG_FILE)) {
            return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
        }
    } catch (error) {
        logger.warn(`读取配置文件失败: ${error.message}`);
    }

    // 返回默认配置
    return {
        tablesConfig: {},
        defaultConfig: {
            enabled: true,
            generateDocs: true,
            generateTypes: true,
            includeInSummary: true
        }
    };
}

/**
 * 获取表的配置
 * @param {string} tableName 表名
 * @param {Object} tablesConfig 所有表配置
 * @returns {Object} 表配置
 */
function getTableConfig(tableName, tablesConfig) {
    const defaultConfig = tablesConfig.defaultConfig || {
        enabled: true,
        generateDocs: true,
        generateTypes: true,
        includeInSummary: true
    };

    return {
        ...defaultConfig,
        ...(tablesConfig.tablesConfig[tableName] || {})
    };
}

/**
 * 根据配置判断是否应当处理该表
 * @param {string} tableName 表名
 * @param {Object} tableConfig 表配置
 * @returns {boolean} 是否处理
 */
function shouldProcessTable(tableName, tableConfig) {
    return tableConfig.enabled !== false;
}

/**
 * 根据配置判断是否应当生成特定类型的文档
 * @param {string} tableName 表名
 * @param {Object} tableConfig 表配置
 * @param {string} docType 文档类型 ('docs'|'types')
 * @returns {boolean} 是否生成
 */
function shouldGenerateDoc(tableName, tableConfig, docType) {
    if (docType === 'docs') {
        return tableConfig.generateDocs !== false;
    } else if (docType === 'types') {
        return tableConfig.generateTypes !== false;
    }
    return true;
}

// 加载TokenCache模块
const TokenCache = require('./tokenCache');

// 初始化Token缓存
const tokenCache = new TokenCache({
    apiBaseUrl: AUTO_API_BASE_URL,
    projectId: PROJECT_ID,
    schema: SCHEMA_NAME
});

// 使用fetch API发起HTTP请求
async function fetchApi(url, method, body, headers = {}) {
    logger.log(`发起API请求: ${method} ${url}`);
    return tokenCache.fetchApi(url, method, body, headers);
}

// 获取token
async function get_token(forceRefresh = false, retryCount = 0) {
    try {
        // 检查是否强制刷新token
        if (forceRefresh || REFRESH_TOKEN) {
            logger.log('强制刷新Token，清除缓存');
            tokenCache.clearToken();
        }

        // 如果启用离线模式和模拟token
        if (OFFLINE_MODE && USE_MOCK_TOKEN) {
            logger.log('离线模式：使用模拟Token');
            return MOCK_TOKEN;
        }

        // 尝试获取token
        logger.log('尝试获取token...');
        const token = await tokenCache.ensureToken(forceRefresh);
        logger.log('获取token成功');
        return token;
    } catch (error) {
        logger.error(`获取token失败 (尝试 ${retryCount + 1}/${MAX_TOKEN_RETRIES})`, error);

        // 如果未达到最大重试次数，尝试重新获取
        if (retryCount < MAX_TOKEN_RETRIES - 1) {
            logger.log(`等待1秒后重试获取token (${retryCount + 2}/${MAX_TOKEN_RETRIES})...`);
            await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒
            return get_token(forceRefresh, retryCount + 1);
        }

        // 如果API获取失败但允许使用模拟token
        if (USE_MOCK_TOKEN) {
            logger.log('API获取失败，使用模拟Token');
            return MOCK_TOKEN;
        }

        throw error;
    }
}

// 获取表列表
async function getTableList(token) {
    try {
        logger.log('尝试获取表列表...');

        // 构建完整的请求头，模拟浏览器请求
        const headers = {
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Accopt-Encoding': 'utf8',
            'Content-Type': 'application/json;charset=UTF-8',
            'Origin': AUTO_API_BASE_URL,
            'Referer': `${AUTO_API_BASE_URL}/index.html`,
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36',
            'x-token': token
        };

        const response = await fetchApi(
            `${AUTO_API_BASE_URL}/findby?tbName=findbytableSchema`,
            'POST',
            {
                tablelist: {
                    tableSchema: SCHEMA_NAME
                }
            },
            headers
        );

        // 处理响应格式，支持直接数组或嵌套在tablelist中的数组
        let tableList = response;
        if (response && !Array.isArray(response) && response.tablelist && Array.isArray(response.tablelist)) {
            logger.log('检测到响应格式包含tablelist字段，提取数组');
            tableList = response.tablelist;
        }

        logger.log(`获取表列表成功，共 ${tableList.length} 个表`);
        logger.saveJsonData('metadata', 'tablelist', tableList);
        return tableList;
    } catch (error) {
        logger.error('获取表列表失败', error);
        throw error;
    }
}

// 获取表的列信息
async function getTableColumns(token, tableName) {
    try {
        logger.log(`尝试获取表 ${tableName} 的列信息...`);

        // 构建完整的请求头，模拟浏览器请求
        const headers = {
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Accopt-Encoding': 'utf8',
            'Content-Type': 'application/json;charset=UTF-8',
            'Origin': AUTO_API_BASE_URL,
            'Referer': `${AUTO_API_BASE_URL}/index.html`,
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36',
            'x-token': token
        };

        const response = await fetchApi(
            `${AUTO_API_BASE_URL}/findby?tbName=findbytablecols`,
            'POST',
            {
                tablecols: {
                    tableSchema: SCHEMA_NAME,
                    tableName: tableName
                }
            },
            headers
        );

        // 处理响应格式，支持直接数组或嵌套在tablecols中的数组
        let columnsList = response;
        if (response && !Array.isArray(response) && response.tablecols && Array.isArray(response.tablecols)) {
            logger.log('检测到响应格式包含tablecols字段，提取数组');
            columnsList = response.tablecols;
        }

        logger.log(`获取表 ${tableName} 的列信息成功，共 ${columnsList.length} 列`);
        logger.saveJsonData(tableName, 'columns', columnsList);
        return columnsList;
    } catch (error) {
        logger.error(`获取表 ${tableName} 的列信息失败`, error);
        throw error;
    }
}

// 生成TypeScript接口定义
function generateTsInterface(tableName, columns, tableComment) {
    logger.log(`为表 ${tableName} 生成TypeScript接口定义`);

    if (!tableComment) tableComment = tableName;

    let interfaceName = tableName
        .split('_')
        .map(part => part.charAt(0).toUpperCase() + part.slice(1))
        .join('');

    let interfaceContent = `/**\n * ${tableComment}接口定义\n */\nexport interface I${interfaceName} {\n`;

    columns.forEach(column => {
        const columnName = column.columnName;
        const columnComment = column.columnComment || columnName;
        const columnType = column.columnType || 'varchar';
        let tsType = 'any';

        // 从columnType中提取实际类型，如varchar(64)中的varchar
        const match = columnType.match(/^([a-z]+)/i);
        if (match && match[1]) {
            const dbType = match[1].toLowerCase();
            tsType = mysqlToTsType[dbType] || 'any';
        }

        // 如果是tinyint(1)，通常是布尔值
        if (columnType === 'tinyint(1)') {
            tsType = 'boolean';
        }

        // 添加注释
        interfaceContent += `  /**\n   * ${columnComment}\n   */\n`;

        // 对于允许为空的列，添加可选标记
        if (column.isNullable === 'YES' || column.columnDefault === null) {
            interfaceContent += `  ${columnName}?: ${tsType};\n\n`;
        } else {
            interfaceContent += `  ${columnName}: ${tsType};\n\n`;
        }
    });

    interfaceContent += '}\n';
    return interfaceContent;
}

// 生成Markdown文档
function generateMdDoc(tableName, columns, tableComment, tsInterface) {
    logger.log(`为表 ${tableName} 生成Markdown文档`);

    if (!tableComment) tableComment = tableName;

    // 从表名中派生更友好的名称
    const friendlyName = tableName
        .split('_')
        .map(part => part.charAt(0).toUpperCase() + part.slice(1))
        .join('');

    // 文档头部
    let mdContent = `# 表名：${tableName}\n\n`;

    // 基本信息
    mdContent += `## 基本信息\n\n`;
    mdContent += `| 项目 | 说明 |\n`;
    mdContent += `|------|------|\n`;
    mdContent += `| 表名 | ${tableName} |\n`;
    mdContent += `| 中文名称 | ${tableComment} |\n`;
    mdContent += `| 主要功能 | 存储${tableComment}相关数据 |\n`;
    mdContent += `| 所属模块 | 根据表名前缀判断的模块 |\n`;
    mdContent += `| 数据量级 | 待评估 |\n`;
    mdContent += `| 是否分区 | 否 |\n\n`;

    // 表结构
    mdContent += `## 表结构\n\n`;
    mdContent += `| 序号 | 字段名称 | 数据类型 | 长度 | 必填 | 主键 | 外键 | 默认值 | 说明 |\n`;
    mdContent += `|------|---------|---------|------|------|------|------|--------|------|\n`;

    columns.forEach((column, index) => {
        const columnName = column.columnName;
        const columnType = column.columnType || '';
        const columnComment = column.columnComment || '';
        const isPrimary = column.columnKey === 'PRI' ? '是' : '否';
        const isRequired = column.isNullable === 'NO' ? '是' : '否';

        // 从columnType中提取长度，如varchar(64)中的64
        let length = '';
        const match = columnType.match(/\((\d+)\)/);
        if (match && match[1]) {
            length = match[1];
        }

        // 获取默认值，如果是NULL则显示为空
        let defaultValue = column.columnDefault === null ? '-' : column.columnDefault;

        // 判断是否为外键（这里简化处理，实际可能需要查询外键约束）
        const isForeignKey = '-';

        mdContent += `| ${index + 1} | ${columnName} | ${columnType.split('(')[0]} | ${length} | ${isRequired} | ${isPrimary} | ${isForeignKey} | ${defaultValue} | ${columnComment} |\n`;
    });

    mdContent += `\n`;

    // 索引信息
    mdContent += `## 索引信息\n\n`;
    mdContent += `| 索引名称 | 字段 | 索引类型 | 索引方式 | 说明 |\n`;
    mdContent += `|----------|------|----------|----------|------|\n`;

    // 添加主键索引
    const primaryKeyColumns = columns.filter(col => col.columnKey === 'PRI').map(col => col.columnName);
    if (primaryKeyColumns.length > 0) {
        mdContent += `| PRIMARY | ${primaryKeyColumns.join(', ')} | PRIMARY | BTREE | 主键索引 |\n`;
    }

    mdContent += `\n`;

    // 字段值域说明
    mdContent += `## 字段值域说明\n\n`;
    mdContent += `| 字段名称 | 值域 | 说明 |\n`;
    mdContent += `|----------|------|------|\n`;
    mdContent += `| is_deleted | 0 | 否 |\n`;
    mdContent += `| is_deleted | 1 | 是 |\n`;
    mdContent += `\n`;

    // 相关数据字典
    mdContent += `## 相关数据字典\n\n`;
    mdContent += `| 字段名称 | 数据字典 | 链接 |\n`;
    mdContent += `|----------|----------|------|\n`;
    mdContent += `\n`;

    // 关联表关系
    mdContent += `## 关联表关系\n\n`;
    mdContent += `| 本表字段 | 关联表 | 关联字段 | 关系类型 | 说明 |\n`;
    mdContent += `|----------|--------|----------|----------|------|\n`;
    mdContent += `\n`;

    // API示例
    mdContent += `## API示例\n\n`;

    // 获取主键字段
    const primaryKey = columns.find(col => col.columnKey === 'PRI') || columns[0];
    const idField = primaryKey.columnName;

    // 查询示例
    mdContent += `### 查询示例\n\n`;
    mdContent += "```typescript\n";
    mdContent += generateApiExample('FIND_LIST', tableName, friendlyName, columns, idField);
    mdContent += "\n```\n\n";

    // 新增示例
    mdContent += `### 新增示例\n\n`;
    mdContent += "```typescript\n";
    mdContent += generateApiExample('ADD', tableName, friendlyName, columns, idField);
    mdContent += "\n```\n\n";

    // 更新示例
    mdContent += `### 更新示例\n\n`;
    mdContent += "```typescript\n";
    mdContent += generateApiExample('UPDATE', tableName, friendlyName, columns, idField);
    mdContent += "\n```\n\n";

    // 删除示例
    mdContent += `### 删除示例\n\n`;
    mdContent += "```typescript\n";
    mdContent += generateApiExample('DELETE', tableName, friendlyName, columns, idField);
    mdContent += "\n```\n\n";

    // TypeScript接口
    mdContent += `## 字段映射的TypeScript接口\n\n`;
    mdContent += "```typescript\n";
    mdContent += tsInterface;
    mdContent += "```\n\n";

    // 注意事项
    mdContent += `## 注意事项\n\n`;
    mdContent += `- 本表的完整字段说明请参考表结构部分\n`;
    mdContent += `- 操作本表时需注意关联表的数据一致性\n`;
    mdContent += `- 添加和更新操作应验证必填字段\n`;
    mdContent += `\n`;

    // 变更历史
    mdContent += `## 变更历史\n\n`;
    mdContent += `| 日期 | 变更人 | 变更内容 |\n`;
    mdContent += `|------|--------|----------|\n`;
    const today = new Date().toISOString().slice(0, 10);
    mdContent += `| ${today} | 系统生成 | 初始化文档 |\n`;

    return mdContent;
}

// 生成表格汇总Markdown文档
function generateTableSummaryMarkdown(tablesSummary, outputDir) {
    const today = new Date().toISOString().slice(0, 10);
    let mdContent = `# 数据库表汇总信息\n\n`;
    mdContent += `> 生成时间: ${today}\n\n`;
    mdContent += `## 表概览\n\n`;
    mdContent += `共计 ${tablesSummary.length} 个表\n\n`;

    // 表格形式展示
    mdContent += `| 序号 | 表名 | 中文名称 | 字段数量 | 是否有主键 | 数据类型 | 文档链接 |\n`;
    mdContent += `|------|------|----------|----------|------------|----------|----------|\n`;

    tablesSummary.forEach((table, index) => {
        const relativeMarkdownPath = path.basename(table.filePath.markdown);
        mdContent += `| ${index + 1} | ${table.tableName} | ${table.tableComment || '-'} | ${table.columnsCount} | ${table.hasPrimaryKey ? '是' : '否'} | ${table.columnTypes.join(', ')} | [查看](${relativeMarkdownPath}) |\n`;
    });

    mdContent += `\n## 表分类统计\n\n`;

    // 按前缀统计表
    const prefixStats = {};
    tablesSummary.forEach(table => {
        // 取表名的前缀（第一个下划线前的部分）
        const prefix = table.tableName.split('_')[0];
        if (!prefixStats[prefix]) {
            prefixStats[prefix] = [];
        }
        prefixStats[prefix].push(table.tableName);
    });

    mdContent += `### 按前缀分类\n\n`;
    mdContent += `| 前缀 | 表数量 | 表列表 |\n`;
    mdContent += `|------|--------|--------|\n`;

    Object.keys(prefixStats).forEach(prefix => {
        mdContent += `| ${prefix} | ${prefixStats[prefix].length} | ${prefixStats[prefix].join(', ')} |\n`;
    });

    // 保存Markdown文档
    const mdFilePath = path.join(outputDir, `tables_summary.md`);
    fs.writeFileSync(mdFilePath, mdContent);
    logger.log(`表信息汇总已保存到: ${mdFilePath}`);

    return mdFilePath;
}

// 生成类型索引文件
function generateTypeIndexFile(processedTables, typesDir) {
    logger.log('开始生成类型索引文件...');

    // 修改：获取所有表，不仅限于标记为tsFileGenerated的表
    // 获取所有在types目录下存在对应.ts文件的表
    const allTypeFiles = [];
    try {
        const files = fs.readdirSync(typesDir);
        // 获取所有.ts文件（排除index.ts）
        const tsFiles = files.filter(file => file.endsWith('.ts') && file !== 'index.ts');
        logger.log(`在目录 ${typesDir} 中找到 ${tsFiles.length} 个TypeScript文件`);

        // 对于每个ts文件，创建表项
        tsFiles.forEach(file => {
            const tableName = file.replace('.ts', '');
            allTypeFiles.push({
                tableName,
                tsFilePath: path.join(typesDir, file),
                hasTsFile: true
            });
        });
    } catch (error) {
        logger.error(`读取类型目录失败: ${error.message}`);
    }

    if (allTypeFiles.length === 0) {
        logger.log('没有找到TypeScript接口文件，跳过生成索引文件');
        return;
    }

    // 生成索引文件内容
    let indexContent = `/**
 * 自动生成的数据表接口类型定义索引
 * 
 * 本文件导出所有由数据表生成的TypeScript接口定义
 * 使用时可以通过此文件统一导入所需的接口类型
 * 
 * 生成时间: ${new Date().toISOString()}
 */

/**
 * 自动生成的数据库表对应TypeScript类型定义
 * 
 * 此文件由生成工具自动创建，请勿手动修改
 * 如需修改表结构，请通过数据库变更并重新生成
 */

// API通用类型定义
/**
 * HTTP响应基础接口
 */
export interface IHttpResponse<T = any> {
  /**
   * 状态码
   */
  code: number;
  
  /**
   * 响应消息
   */
  msg: string;
  
  /**
   * 响应数据
   */
  data: T;
  
  /**
   * 请求是否成功
   */
  success: boolean;
  
  /**
   * 时间戳
   */
  timestamp?: number;
}

/**
 * 通用查询参数接口
 */
export interface IQueryParams {
  /**
   * 当前页码
   */
  page: number;
  
  /**
   * 每页数据量
   */
  pageSize: number;
  
  /**
   * 排序配置
   */
  orderBy?: {
    /**
     * 排序字段
     */
    field: string;
    
    /**
     * 排序方向
     */
    order: 'asc' | 'desc';
  };
  
  /**
   * 查询条件
   */
  condition?: Array<{
    /**
     * 字段名
     */
    field: string;
    
    /**
     * 查询值
     */
    value: any;
    
    /**
     * 比较操作符
     */
    compare: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'in' | 'nin';
  }>;
}

/**
 * 分页响应接口
 */
export interface IPaginationResult<T = any> {
  /**
   * 总记录数
   */
  total: number;
  
  /**
   * 当前页码
   */
  current: number;
  
  /**
   * 每页数据量
   */
  pageSize: number;
  
  /**
   * 总页数
   */
  pages: number;
  
  /**
   * 数据列表
   */
  records: T[];
}

// 导出查询结果类型
export type FindListResult<T> = IPaginationResult<T>;

// 导出各表接口类型
`;

    // 对于每个表，添加export语句
    // 按照字母顺序排序表名，使导出更有组织性
    allTypeFiles.sort((a, b) => a.tableName.localeCompare(b.tableName));

    // 记录找到的接口数量
    logger.log(`准备导出 ${allTypeFiles.length} 个TypeScript接口`);

    // 导出所有表的接口
    allTypeFiles.forEach(table => {
        const interfaceName = getInterfaceNameFromTableName(table.tableName);
        indexContent += `export { ${interfaceName} } from './${table.tableName}';\n`;
    });

    // 写入索引文件
    const indexFilePath = path.join(typesDir, 'index.ts');
    try {
        fs.writeFileSync(indexFilePath, indexContent);
        logger.log(`类型索引文件已保存到: ${indexFilePath}`);
        logger.log(`成功导出 ${allTypeFiles.length} 个接口到索引文件`);
    } catch (error) {
        logger.error(`保存类型索引文件失败: ${error.message}`);
    }

    return indexFilePath;
}

// 辅助函数：从表名获取接口名
function getInterfaceNameFromTableName(tableName) {
    // 将表名转换为驼峰式，并添加I前缀
    return 'I' + tableName.split('_').map(part =>
        part.charAt(0).toUpperCase() + part.slice(1)
    ).join('');
}

// 主函数
async function main() {
    try {
        logger.log('开始执行主函数...');
        logger.log(`Token刷新: ${REFRESH_TOKEN ? '强制刷新' : '使用缓存(如果有效)'}`);

        // 创建输出目录
        const outputDir = path.resolve(__dirname, '../tables');
        const typesDir = path.resolve(__dirname, '../types');

        if (!fs.existsSync(outputDir)) {
            fs.mkdirSync(outputDir, { recursive: true });
            logger.log(`创建输出目录: ${outputDir}`);
        }

        if (!fs.existsSync(typesDir)) {
            fs.mkdirSync(typesDir, { recursive: true });
            logger.log(`创建类型定义目录: ${typesDir}`);
        }

        // 读取表配置
        const tablesConfig = getTablesConfig();
        logger.log(`读取表配置完成，默认配置: ${JSON.stringify(tablesConfig.defaultConfig)}`);

        // 设置API日志记录状态
        apiLogger.setEnabled(ENABLE_API_LOGGING);

        // 清除API日志（如果指定）
        if (CLEAR_API_LOGS) {
            apiLogger.clearLogs();
            logger.log('API日志已清除');
        }

        // 自定义Schema名称
        const schemaIndex = process.argv.indexOf('--schema');
        if (schemaIndex > -1 && schemaIndex < process.argv.length - 1) {
            SCHEMA_NAME = process.argv[schemaIndex + 1];
            logger.log(`使用自定义Schema名称: ${SCHEMA_NAME}`);
        }

        // 获取token
        logger.log('获取token...');
        const token = await get_token();
        logger.log(`Token获取成功: ${token.substring(0, 10)}...`);

        // 获取表列表
        logger.log('获取表列表...');
        const tableList = await getTableList(token);
        logger.log(`获取到 ${tableList.length} 个表`);

        // 提取所有表名
        const allTableNames = tableList.map(table => table.tableName);
        logger.log(`提取到的所有表名: ${allTableNames.join(', ')}`);

        // 保存所有表名列表为JSON
        logger.saveJsonData('metadata', 'all_table_names', allTableNames);

        // 创建表信息汇总数组
        const tablesSummary = [];
        const processedTables = []; // 成功处理的表
        const skippedTables = [];   // 跳过的表
        const failedTables = [];    // 处理失败的表

        // 处理每个表
        for (const table of tableList) {
            const tableName = table.tableName;
            const tableComment = table.tableComment || tableName;

            // 获取表配置
            const tableConfig = getTableConfig(tableName, tablesConfig);

            // 检查是否应该处理该表
            if (!shouldProcessTable(tableName, tableConfig)) {
                logger.log(`表 ${tableName} 已在配置中禁用，跳过处理`);
                skippedTables.push({
                    tableName,
                    reason: '配置已禁用'
                });
                continue;
            }

            logger.log(`开始处理表: ${tableName}`);

            try {
                // 记录开始处理表
                logger.startTableProcessing(tableName, tableComment);

                logger.log(`表 ${tableName} 的注释: ${tableComment}`);
                logger.saveJsonData(tableName, 'info', table);
                logger.tableLog(tableName, 'INFO', `获取表信息成功`, table);

                // 获取列信息
                logger.log(`获取表 ${tableName} 的列信息...`);
                const columns = await getTableColumns(token, tableName);
                logger.log(`表 ${tableName} 有 ${columns.length} 列`);
                logger.tableLog(tableName, 'DATA', `获取到表结构，共 ${columns.length} 列`);

                // 收集表信息汇总
                const tableInfo = {
                    tableName: tableName,
                    tableComment: tableComment,
                    columnsCount: columns.length,
                    createTime: new Date().toISOString(),
                    hasPrimaryKey: columns.some(col => col.columnKey === 'PRI'),
                    primaryKey: columns.filter(col => col.columnKey === 'PRI').map(col => col.columnName),
                    columnTypes: Array.from(new Set(columns.map(col => {
                        // 提取类型，例如从varchar(64)中提取varchar
                        const match = col.columnType ? col.columnType.match(/^([a-z]+)/i) : null;
                        return match && match[1] ? match[1].toLowerCase() : 'unknown';
                    }))),
                    enabledInConfig: tableConfig.enabled !== false,
                    generateDocs: tableConfig.generateDocs !== false,
                    generateTypes: tableConfig.generateTypes !== false,
                    description: tableConfig.description || `${tableComment}表`,
                    filePath: {
                        markdown: path.join(outputDir, `${tableName}.md`),
                        typescript: path.join(typesDir, `${tableName}.ts`),
                        json: path.join(JSON_DATA_DIR, tableName, 'columns.json')
                    }
                };

                // 只有配置允许才加入汇总
                if (tableConfig.includeInSummary !== false) {
                    tablesSummary.push(tableInfo);
                }

                // 根据配置决定是否生成TypeScript接口
                if (shouldGenerateDoc(tableName, tableConfig, 'types')) {
                    const tsInterface = generateTsInterface(tableName, columns, tableComment);
                    logger.tableLog(tableName, 'GENERATE', `生成了TypeScript接口定义`);

                    // 保存TypeScript接口定义
                    const tsFilePath = path.join(typesDir, `${tableName}.ts`);
                    fs.writeFileSync(tsFilePath, tsInterface);
                    logger.log(`TypeScript接口已保存到: ${tsFilePath}`);
                    logger.tableLog(tableName, 'SAVE', `保存了TypeScript接口定义文件`, { path: tsFilePath });
                    tableInfo.tsFileGenerated = true;
                } else {
                    logger.log(`表 ${tableName} 配置为不生成TypeScript接口，已跳过`);
                    tableInfo.tsFileGenerated = false;
                }

                // 根据配置决定是否生成Markdown文档
                if (shouldGenerateDoc(tableName, tableConfig, 'docs')) {
                    // 生成TypeScript接口用于文档（即使不保存）
                    const tsInterface = tableInfo.tsFileGenerated ?
                        fs.readFileSync(path.join(typesDir, `${tableName}.ts`), 'utf8') :
                        generateTsInterface(tableName, columns, tableComment);

                    const mdDoc = generateMdDoc(tableName, columns, tableComment, tsInterface);
                    logger.tableLog(tableName, 'GENERATE', `生成了Markdown文档`);

                    // 保存Markdown文档
                    const mdFilePath = path.join(outputDir, `${tableName}.md`);
                    fs.writeFileSync(mdFilePath, mdDoc);
                    logger.log(`Markdown文档已保存到: ${mdFilePath}`);
                    logger.tableLog(tableName, 'SAVE', `保存了Markdown文档文件`, { path: mdFilePath });
                    tableInfo.mdFileGenerated = true;
                } else {
                    logger.log(`表 ${tableName} 配置为不生成Markdown文档，已跳过`);
                    tableInfo.mdFileGenerated = false;
                }

                // 记录变更历史
                logger.recordTableChanges(tableName, 'CREATE', 'system', '初始创建文档 (API数据)');

                // 记录处理完成
                logger.finishTableProcessing(tableName, {
                    columnCount: columns.length,
                    generateTypes: tableInfo.tsFileGenerated,
                    generateDocs: tableInfo.mdFileGenerated,
                    files: [
                        { type: 'json', path: path.join(JSON_DATA_DIR, tableName, 'columns.json') },
                        ...(tableInfo.tsFileGenerated ? [{ type: 'ts', path: tableInfo.filePath.typescript }] : []),
                        ...(tableInfo.mdFileGenerated ? [{ type: 'md', path: tableInfo.filePath.markdown }] : [])
                    ]
                });

                logger.log(`表 ${tableName} 处理完成`);
                processedTables.push(tableInfo);
            } catch (tableError) {
                logger.error(`处理表 ${tableName} 失败`, tableError);
                failedTables.push({
                    tableName,
                    error: tableError.message,
                    timestamp: new Date().toISOString()
                });
            }
        }

        // 保存处理结果统计
        const processSummary = {
            timestamp: new Date().toISOString(),
            totalTables: tableList.length,
            processedCount: processedTables.length,
            skippedCount: skippedTables.length,
            failedCount: failedTables.length,
            skippedTables,
            failedTables
        };

        logger.saveJsonData('metadata', 'process_summary', processSummary);

        // 保存表信息汇总为JSON
        logger.saveJsonData('metadata', 'tables_summary', tablesSummary);

        // 生成表信息汇总的Markdown文档
        generateTableSummaryMarkdown(tablesSummary, outputDir);

        // 生成类型索引文件
        generateTypeIndexFile(processedTables, typesDir);

        logger.log('全部表处理完成！');
        logger.log(`总计: ${tableList.length} 个表, 成功: ${processedTables.length}, 跳过: ${skippedTables.length}, 失败: ${failedTables.length}`);

        // 如果有配置管理工具，更新配置
        if (tableConfigManager) {
            logger.log('正在更新表配置...');
            tableConfigManager.generateTableConfig();
        }
    } catch (error) {
        logger.error('处理失败', error);
        process.exit(1);
    }
}

// 执行主函数
main();